package netTracker.network;
import java.util.HashMap;

import netTracker.Note;
import netTracker.Song;

/**
 *	Represents a message with a source address, message, and possibly other information.
 *	Modified by David Cummings from the original source by Brittney and Lyly.
 */

@SuppressWarnings("serial")

public class Message implements java.io.Serializable {
	private Address src;			// Source address of the message.
	private Address otherAddr;	// Address of another node, used in LOOKUP for example
	private HashMap<Address, Integer> addressBook;	// Address book used in LIST SERVERS request
	private int number=-1;		// The numerical content of a message. -1 indicates an unset number.
	private String msg;			// The String content of a message.
	private String tag;			// The tag of the message.
	private Song song;			// The Song content of a message.
	Note note;						// The Note content of a message.

	/** 
	 * Constructs a String message with a tag.
	 * @param tag the tag of the message 
	 * @param msg the contents of the message
	 * @param src the source address of the node sending the message
	 * */
	public Message(String tag, String msg, Address src){
		this.tag = tag;
		this.msg = msg;
		this.src = src;
	}
	
	/** 
	 * Constructs a numerical message with a tag.
	 * @param tag the tag of the message 
	 * @param number the numerical contents of the message
	 * @param src the source address of the node sending the message
	 * */
	public Message(String tag, int number, Address src){
		this.tag = tag;
		this.number = number;
		this.src = src;
	}
	
	
	/** 
	 * Constructs a message with only a tag but no contents.
	 * @param msg the tag of the message
	 * @param src the source address of the node sending the message
	 * */
	public Message(String tag, Address src){
		this.tag = tag;
		this.src = src;
	}
	
	/** 
	 * Constructs a message without a source. Warning:
	 * if using this constructor, the source of a
	 * message should be set before sending, as a null
	 * source address may result in problems for receivers 
	 * of the message.
	 *  
	 * @param msg the contents of the message
	 * */
	public Message(String msg){
		this.msg = msg;
	}
	
	/**
	 * Constructs a message with an address as contents.
	 * @param tag the tag of the message
	 * @param otherAddr the address contents
	 * @param src the source address of the message
	 */
	public Message(String tag, Address otherAddr, Address src) {
		this.tag = tag;
		this.otherAddr=otherAddr;
		this.src=src;
	}

	/**
	 * @return the message tag
	 */
	public String getTag() {
		return tag;
	}

	/**
	 * @param tag the tag to set
	 */
	public void setTag(String tag) {
		this.tag = tag;
	}
	
	/**
	 * Returns the source address of the message 
	 * @return the source address of the message */ 
	public Address getSrc (){
		return src;
	}
	
	/**
	 *	Returns the contents of the message
	 *	@return the contents of the message 
	 */
	public String getMsg () { 
		return msg; 
	}

	/**
	 *	Sets the contents of the message
	 *	@param m the message to set
	 *	@return the message set
	 */
	public String setMsg (String msg){
		return this.msg = msg; 
	}

	/**
	 * Sets the source of the message
	 * @param src the source address to set
	 * @return the address set
	 */
	public Address setSrc (Address src){
		return this.src = src;
	}
	
	/**
	 * @return the numerical content of the message
	 */
	public int getNumber() {
		return number;
	}

	/**
	 * @param number the number to set
	 */
	public void setNumber(int number) {
		this.number = number;
	}

	public void setOtherAddr(Address otherAddr) {
		this.otherAddr = otherAddr;
	}

	public Address getOtherAddr() {
		return otherAddr;
	}
	
	/**
	 * Sets an address book to send with the message.
	 * Used when sending a LISTSERVERS query to the name server.
	 * @param addressBook the address book to sent
	 */
	public void setAddressBook(HashMap<Address,Integer> addressBook){
		this.addressBook = addressBook;
	}
	
	/**
	 * Gets the address book stored in this message.
	 * @return the address book stored in this message
	 */
	public HashMap<Address,Integer> getAddressBook(){
		return addressBook;
	}
	
	/** 
	 * Returns a string representation of this message.
	 * @return a string representation of this message.
	 */
	public String toString(){
		String message=tag;
		if(msg!=null)
			message+= (" "+msg);
		if(number!=-1)
			message+= (" "+number);
		if(addressBook != null)
			message+=addressBook.toString();
		return (message + " from:"+src);
	}

	public void setSong(Song song) {
		this.song = song;
	}
	
	public Song getSong(){
		return song;
	}

	public void setNote(Note note) {
		this.note = note;
	}
	
	public Note getNote() {
		return note;
	}
}
